package com.tedu.api.list;

import org.junit.Test;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.function.BiConsumer;

/**
 * 包位置：ava.util
 * Map与Collection同等级顶级接口
 * Map映射接口
 * 作用：一个元素有两个对象构成，分别为Key【键】和Value【值】构成
 *       获取数据：采用键取值 ，通常与数据库搭配，获取字段下的值
 *特点:无序、无下标、键不可以重复【唯一性]、值可以重复
 *  Map接口---无法直接实例化【创建]对象---实现类
 *  HashMap[常用]:有哈希算法底层实现，存储性能快，键可以存null，但只允许一个
 *                 主要是通过键找值
 * LinkedHashMap[不常用]：方法与HashMap，用于日志记录按照时间顺序
 *  TreeMap[不用]: 性能：插入删除非常慢、多线程不安全、占用内存
 * 【算法：红黑树实现--需要进行树的旋转和调整以保持平衡】
 *  Hashtable[不用]:jdk1.8  性能：插入删除非常慢、多线程不安全、占用内存
 * 【算法：哈希算法】
 * Hashtable--被ConcurrentHashMap取代
 * ConcurrentHashMap[较为常用]:学习多线程
 * 重点:Map接口中方法【Map接口方法与HashMap方法类似 90%]
 *
 * 12个集合类【保存状态】--保存数据--操作：增删改查【写--看懂】
 */
public class MapAPI {
    @Test
    public void testMap(){
        //创建Map映射接口--多态      键---值     id-19870502
        Map<Object,String> map=new HashMap<>();
        //键--->值  添加元素 ：K-V
        /**
         * put("键”，“值”)     返回值：V  value值
         * 作用：存键值对形态一组数据
         */
        map.put("西游记","孙悟空");
        map.put("红楼梦","林黛玉");
        map.put("水浒传","武松");
        map.put("三国志","诸葛亮");
        System.out.println("map映射存储数据："+map);
        /**
         * get(E e)  根据键找到对应值   返回值：V   value
         * remove（K key）通过key删除一组键值对
         * size（）获取map元素总数，   返回值：int
         */
        //找到map集合中 武松的元素--V value值
        String wusong=map.get("水浒传");
        System.out.println("通过键找到值："+wusong);
        //get()键不存在--返回值的默认值：基本类型、引用类型：null值
        String zhuge=map.get("三国");
        System.out.println("通过键找到值："+zhuge);
        map.remove("三国志");
        System.out.println("删除后的映射："+map);
        /**
         * containsKey()
         * 作用：判断map中元素 “对象:键” 是否存在
         * containsValue()
         *  作用：判断map中元素 “对象:值” 是否存在
         */
        boolean bk= map.containsKey("红楼梦");
        System.out.println("map元素：键"+bk);
        boolean bv= map.containsValue("武松");
        System.out.println("map元素：值"+bv);
    }
    /**
     * map元素遍历      键-->值
     * keySet()    获取map元素中所有的键
     * values()    获取map元素中所有的值
     * entrySet()   获取map元素中所有的键与值
     */
    @Test
    public void testKVE(){
        //创建map映射集合
        Map<Object,String> map=new HashMap<>();
        map.put("默","那英");
        map.put("告白气球","周杰伦");
        map.put("套马杆","乌兰图雅");
        map.put("丑八怪","薛之谦");
        //1.获取map集合元素中 键 数据 KeySet（）  返回值：Set集合
        Set<Object> sets=map.keySet();
        //1.2遍历从map元素中获取的键--数据
        for(Object keys:sets){
            System.out.println("输出map元素中："+keys);
        }
        //2.获取map集合元素中  值  数据  values()   返回值：Collection
        Collection<String> cs=map.values();
        //2.2遍历从map元素中获取的值--数据
        for(String values:cs){
            System.out.println("输出map元素中："+values);
        }
        //3.获取map集合元素【entrys】中 数据：键与值  entrySet()
        //返回值：Set<Map.Entry<K,V>>
        //Map.Entry<K,v>  保存map元素所有组数据！使用Map.Entry
        //Entry内部接口：保存map元素所有组数据！使用Map.Entry
       Set<Map.Entry<Object,String>> entrys=map.entrySet();
        //获取map映射集合所有元素[entry]
        //3.1遍历map所有的键与值【所有entry/元素/数据--成对】
        for(Map.Entry<Object,String>entry:entrys){
            //3.2获取键   getKey    注意：类型
            Object Keys=entry.getKey();
            //3.3获取值   getValue  注意：类型
            String values=entry.getValue();
            //3.4打印
            System.out.println(Keys+" "+values);
        }
    }
    /**
     * forEach(new BiConsumer（）)   遍历map中所有  对元素/entry
     * 理解：for+entrySet（）集合=forEach（）
     * BiConsumer接口参数  传入
     * 理解：针对map存储问题--封装接口--提供方法：accept（） 所有组entry
     */
    @Test
    public void testForEach(){
        //创建map映射集合
        Map<Object,String> map=new HashMap<>();
        map.put("默","那英");
        map.put("告白气球","周杰伦");
        map.put("套马杆","乌兰图雅");
        map.put("丑八怪","薛之谦");
        //Map映射集合--提供--方法，forEach（）
        map.forEach(new BiConsumer<Object, String>(){
            //accept(K,V)方法：获取到Entry中--每组entry
            //K---键   V--值
            public void accept(Object o, String s) {
                System.out.println(o+" "+s);
            }
        });
    }
    /**
     * HashMap映射集合
     * HashMap中方法基本一致
     * putIfAbsent（）
     * 作用：用来给HashMap映射集合存入【entry/一组数据：一组键值】
     *      如果存入一组数据，不存在的键，插入HashMap
     *                       存在的键，不插入HashMap
     *      哈希算法--唯一性
     */
    @Test
    public void testHashMap(){
        //创建map映射集合
        Map<Object,String> map=new HashMap<>();
        map.putIfAbsent("演员","薛之谦");
        map.put("默","那英");
        map.put("告白气球","周杰伦");
        map.put("套马杆","乌兰图雅");
        map.put("丑八怪","薛之谦");
        System.out.println("HashMap存值" + map);
    }
}
